struct Stream

Owner: Alex

Purpose and Documentation

This page contains information for the functions that are used to manipulate input and output streams.

Due to a limited amount of memory on the PIC, it is quite wasteful to have several static arrays occupying space at all times. However, we do need to have a reasonably large buffer for output streams, particularly the speech and serial outputs. Streams operate as follows:
  • Any function can call push_string(stream, string), which will copy the string into a dynamically expanding queue.
  • When the program is ready to read from the stream, calling pop_char(stream) to get the first char out of the string.
  • When all the available characters have been sent, is_empty(stream) will return 1.

Syntax


typedef struct Link
{
    char element;
    struct Link* next;
} Link;
 
typedef struct Stream
{
    Link* head;
    Link* tail;
} Stream;
 

Usage

Use these functions to add characters to a particular I/O stream.

Input Arguments

  • Stream* stream: This is a pointer to the stream being written/read from.
  • char* string: A string to append to the tail of the stream. It must be a null terminated string.

Output Arguments

  • stream->tail
  • stream->head

Return Value

  • char: The character at the end of the stream. The stream will automatically advance when this is read.

Settings and Registers

Read

  • None

Write

  • None

Operation

The queue takes the form of a singly linked list, as using a vector could cause the streams to 'jump around' in memory as they were allocated and deallocated. When a character is added to the stream, a new element is created and the char is added to the tail of the list. When a character is read from the stream, it is removed from the head of the stream.

Code

#include <stdio.h>
#include <stdlib.h>
 
typedef struct Link
{
    char element;
    struct Link* next;
} Link;
 
typedef struct Stream
{
    Link* head;
    Link* tail;
} Stream;
 
void push_char(Stream* stream, char character)
{
    Link* newLink;
    newLink = (Link*)malloc(sizeof(Link)); //Create new link in list
    stream->tail->element = character; //Copy new value into list
    stream->tail->next = newLink; //Tell the previous link where to find the new link
 
    newLink->next = NULL;
    newLink->element = '\0';
 
    stream->tail = newLink; //Tell the stream where to find the end of the string
}
 
void push_string(Stream* stream, char* string)
{
    int i;
    for(i = 0; string[i] != '\0'; i++)
    {
        push_char(stream,string[i]);
    }
    push_char(stream,'\0');
}
 
void push_block(Stream* stream, char* string, int length)
{
    int i;
    for(i = 0; i < length; i++)
    {
        push_char(stream,string[i]);
    }
    push_char(stream,'\0');
}
 
char pop_char(Stream* stream)
{
    char retval = stream->head->next->element;
    Link* oldLink;
    Link* nextLink;
 
    oldLink = stream->head;
    nextLink = stream->head->next;
 
    stream->head = nextLink; //Advance the stream
 
    free(oldLink); //Get rid of the link that was just read
 
    return retval;
}
 
int is_empty(Stream* stream)
{
    if(stream->head->next == stream->tail)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}